package com.edoomath.api.servcice.impl;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dao;
import com.edoomath.api.dao.CourseDao;
import com.edoomath.api.dao.CourseItemDao;
import com.edoomath.api.dao.CourseMaterialDao;
import com.edoomath.api.dao.UserCourseMaterialDao;
import com.edoomath.api.dao.UserDao;
import com.edoomath.api.handler.TempFileHandler;
import com.edoomath.api.servcice.MatrialService;
import com.edoomath.entity.course.CourseItem;
import com.edoomath.entity.course.CourseItemStat;
import com.edoomath.entity.course.CourseMaterail;
import com.edoomath.entity.mail.MailTask;
import com.edoomath.entity.user.User;
import com.edoomath.entity.usercourse.DownloadType;
import com.edoomath.entity.usercourse.UserCourseMaterial;

/**
 * 
 * @author mohanlan
 *
 */
@Service("matrialService")
public class MaterialServiceImpl implements MatrialService {
	
	private static final Logger logger = LoggerFactory.getLogger(MatrialService.class);

	@Dao
	private UserDao userDao;

	@Dao
	private CourseDao courseDao;

	@Dao
	private CourseItemDao courseItemDao;
	
	@Dao
	private CourseMaterialDao courseMaterialDao;

	@Dao
	private UserCourseMaterialDao userCourseMaterialDao;

	@Autowired
	private GenericDaoSupport genericDaoSupport;

	@Autowired
	private TempFileHandler tempFileHandler;
	
	/*
	 * (non-Javadoc)
	 * @see com.edoomath.api.servcice.MatrialService#validateMailTask(java.lang.String, java.util.List)
	 */
	public void validateMailTask(String unionid, List<Long> materialIds, List<Long> extraMaterialIds) {
		this.validateUserCourseMaterial(unionid, materialIds);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.edoomath.api.servcice.MailTaskService#create(java.lang.String,
	 * java.lang.String, java.lang.Long)
	 */
	public void createMailTask(String unionid, String email, List<Long> materialIds, List<Long> extraMaterialIds) {

		User user = userDao.loadUser(unionid);

		if (!user.hasEmail()) {
			user.bindEmail(email);
			genericDaoSupport.update(user);
		}

		// before. validate user can download file or not
		Map<String, UserCourseMaterial> userCourseMaterials = this.validateUserCourseMaterial(unionid, materialIds);

		for (Long materialId : materialIds) {

			CourseMaterail courseMaterail = courseMaterialDao.loadCourseMaterail(materialId);

			// 1. update or save userCourseMaterial
			UserCourseMaterial userCourseMaterial = userCourseMaterials.get(materialId.toString());
			userCourseMaterial = this.updateUserCourseMaterial(userCourseMaterial, user, courseMaterail, user.getEmail());

			// 2. create task here
			String content = "您好，您在小程序【陆老师小打卡】请求下载的文件【" + courseMaterail.getName() + "】在该邮件的附件中，请注意查收。";
			MailTask mailTask = new MailTask(user.getEmail(), "陆老师小打卡资料下载", content, courseMaterail.getName(),
					courseMaterail.getDownloadUrl(), new Date());
			genericDaoSupport.save(mailTask.initliaze());
			
			CourseItem courseItem = userCourseMaterial.getCourseMaterail().getCourseItem();
			if(courseItem != null) {
				CourseItemStat stat = courseItemDao.loadCourseItemStat(courseItem);
				if(stat != null) {
					genericDaoSupport.update(stat.addDownloadcount());
				}
			}
			
		}
		
		if(CollectionUtils.isNotEmpty(extraMaterialIds)) {
			
			try {
				List<String> idStrings = new ArrayList<String>();
				for(Long id : extraMaterialIds) {
					idStrings.add(id.toString());
				}
				
				Date dayBefore = DateUtils.addDays(new Date(), -1);
				
				String fileName = String.join("-", idStrings) + ".zip";
				UserCourseMaterial userCourseMaterial = userCourseMaterialDao.loadUserCourseMaterial(unionid, DownloadType.EMAIL, fileName);
				
				if(userCourseMaterial == null) {
					
					List<CourseMaterail> materails = courseDao.listMaterials(extraMaterialIds);
					String url = tempFileHandler.generateZipFile(materails);
					
					userCourseMaterial = new UserCourseMaterial(user, fileName, DownloadType.EMAIL, user.getEmail());
					genericDaoSupport.save(userCourseMaterial.initliaze());
					
					String content = "您好，您在小程序【陆老师小打卡】请求下载的文件【追加任务资料包】在该邮件的附件中，请注意查收。";
					MailTask mailTask = new MailTask(user.getEmail(), "陆老师小打卡资料下载", content, "追加任务资料包",
							url, new Date());
					genericDaoSupport.save(mailTask.initliaze());
					
				} else if (dayBefore.after(userCourseMaterial.getLastModifyTime())) {
					
					List<CourseMaterail> materails = courseDao.listMaterials(extraMaterialIds);
					String url = tempFileHandler.generateZipFile(materails);
					genericDaoSupport.update(userCourseMaterial.update());
					
					String content = "您好，您在小程序【陆老师小打卡】请求下载的文件【追加任务资料包】在该邮件的附件中，请注意查收。";
					MailTask mailTask = new MailTask(user.getEmail(), "陆老师小打卡资料下载", content, "追加任务资料包",
							url, new Date());
					genericDaoSupport.save(mailTask.initliaze());
					
				}
				
			} catch (UnsupportedEncodingException e) {
				logger.error("email task faild with error", e);
				throw BusinessException.newInstance("500", "追加任务zip包发送邮件失败");
			}
			
			
		}
		
		
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.edoomath.api.servcice.MatrialService#generateCopyUrl(java.lang.
	 * String, java.util.List)
	 */
	public List<UserCourseMaterial> generateCopyUrl(String unionid, List<Long> materialIds) {
		
		List<UserCourseMaterial> result = new ArrayList<UserCourseMaterial>();

		Date dayBefore = DateUtils.addDays(new Date(), -1);
		User user = userDao.loadUser(unionid);

		List<UserCourseMaterial> userCourseMaterials = userCourseMaterialDao.listMaterials(unionid, DownloadType.COPY_LINK, materialIds);
		Map<String, UserCourseMaterial> userCourseMaterialsMap = com.demo2do.core.utils.CollectionUtils
				.constructMapValue(userCourseMaterials, "courseMaterail.id");

		List<CourseMaterail> materails = courseDao.listMaterials(materialIds);
		for (CourseMaterail materail : materails) {

			UserCourseMaterial userCourseMaterial = userCourseMaterialsMap.get(materail.getId().toString());

			if (userCourseMaterial == null || dayBefore.after(userCourseMaterial.getLastModifyTime())) {
				String url = tempFileHandler.generateTempFile(materail);
				userCourseMaterial = new UserCourseMaterial(user, materail, DownloadType.COPY_LINK, url);
				genericDaoSupport.save(userCourseMaterial.initliaze());
				
				CourseItem courseItem = userCourseMaterial.getCourseMaterail().getCourseItem();
				if(courseItem != null) {
					CourseItemStat stat = courseItemDao.loadCourseItemStat(courseItem);
					if(stat != null) {
						genericDaoSupport.update(stat.addDownloadcount());
					}
				}
			}
			
			result.add(userCourseMaterial);
		}
		
		return result;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.edoomath.api.servcice.MatrialService#generateExtraTaskUrl(java.lang.String, java.util.List)
	 */
	public UserCourseMaterial generateExtraTaskUrl(String unioinid, List<Long> extraMaterialIds) {
		
		List<String> idStrings = new ArrayList<String>();
		for(Long id : extraMaterialIds) {
			idStrings.add(id.toString());
		}
		
		Date dayBefore = DateUtils.addDays(new Date(), -1);
		
		User user = userDao.loadUser(unioinid);
		
		String fileName = String.join("-", idStrings) + ".zip";
		UserCourseMaterial userCourseMaterial = userCourseMaterialDao.loadUserCourseMaterial(unioinid, DownloadType.COPY_LINK, fileName);
		
		if(userCourseMaterial == null) {
			List<CourseMaterail> materails = courseDao.listMaterials(extraMaterialIds);
			String url = tempFileHandler.generateTempFile(materails);
			userCourseMaterial = new UserCourseMaterial(user, fileName, DownloadType.COPY_LINK, url);
			genericDaoSupport.save(userCourseMaterial.initliaze());
			
		} else if (dayBefore.after(userCourseMaterial.getLastModifyTime())) {
			List<CourseMaterail> materails = courseDao.listMaterials(extraMaterialIds);
			String url = tempFileHandler.generateTempFile(materails);
			genericDaoSupport.update(userCourseMaterial.update(url));
		}
		
		return userCourseMaterial;
	}

	/**
	 * 
	 * @param unionid
	 * @param materialIds
	 * @return
	 */
	private Map<String, UserCourseMaterial> validateUserCourseMaterial(String unionid, List<Long> materialIds) {

		Date dayBefore = DateUtils.addDays(new Date(), -1);

		List<UserCourseMaterial> userCourseMaterials = userCourseMaterialDao.listMaterials(unionid, DownloadType.EMAIL, materialIds);
		for (UserCourseMaterial userCourseMaterial : userCourseMaterials) {
			if (dayBefore.before(userCourseMaterial.getLastModifyTime())) {
				throw BusinessException.newInstance("500", "24小时内只能下载一次资料");
			}
		}

		return com.demo2do.core.utils.CollectionUtils.constructMapValue(userCourseMaterials, "courseMaterail.id");
	}
	
	/**
	 * 
	 * @param userCourseMaterial
	 * @param user
	 * @param courseMaterail
	 * @param email
	 * @return
	 */
	private UserCourseMaterial updateUserCourseMaterial(UserCourseMaterial userCourseMaterial, User user,
			CourseMaterail courseMaterail, String email) {
		if (userCourseMaterial != null) {
			genericDaoSupport.update(userCourseMaterial.update());
		} else {
			userCourseMaterial = new UserCourseMaterial(user, courseMaterail, DownloadType.EMAIL, email);
			genericDaoSupport.save(userCourseMaterial.initliaze());
		}
		
		return userCourseMaterial;
	}

}
